#include <stdio.h>
#include <inttypes.h>
#include <stdlib.h>
#include <arpa/inet.h> 
#include <unistd.h>
#include <netinet/in.h>
#include <sys/types.h>

#include "system/inet.h"
#include "system/game.h"
#include "system/proc.h"

#define SIZE_ARG 20

extern init_mess_t init;
extern int sock;

//TODO: add help mess
int main(int argc, char *argv[])
{
    struct sockaddr_in serv_addr;
    int direction;
    int8_t ret;
    char mod = 'c';
    char arg_ip[SIZE_ARG] = "127.0.0.1";
    char arg_port[SIZE_ARG] = "2229";
    char arg_size_field_x[SIZE_ARG] = "80";
    char arg_size_field_y[SIZE_ARG] = "20";
    char arg_frame_delay[SIZE_ARG] = "300";
    char arg_time_stamp[SIZE_ARG] = "1";
    char arg_num_clients[SIZE_ARG] = "1";
    char arg_log_file[SIZE_ARG] = "snake_server.log";

    struct timespec cur;

    while ((ret = getopt(argc, argv, "shp:a:x:y:d:t:n:f:")) != -1) 
    {
        switch (ret)
        {
            case 's':
                mod = 's';
            break;

            case 'h':
                printf("%s", HELP_CLIENT);
                printf("\n");
                printf("%s", HELP_SERVER);
                exit(EXIT_SUCCESS);
            break;

            case 'p':
                strncpy(arg_port, optarg, SIZE_ARG);
            break;

            case 'a':
                strncpy(arg_ip, optarg, SIZE_ARG);
            break;
            
            case 'x':
                strncpy(arg_size_field_x, optarg, SIZE_ARG);
            break;

            case 'y':
                strncpy(arg_size_field_y, optarg, SIZE_ARG);
            break;

            case 'd':
                strncpy(arg_frame_delay, optarg, SIZE_ARG);
            break;

            case 't':
                strncpy(arg_time_stamp, optarg, SIZE_ARG);
            break;

            case 'n':
                strncpy(arg_num_clients, optarg, SIZE_ARG);
            break;

            case 'f':
                strncpy(arg_log_file, optarg, SIZE_ARG);
            break;
        }
    }


    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(atoi(arg_port));
    serv_addr.sin_addr.s_addr = Inet_addr(arg_ip);
    
    if (mod == 'c')
    {
        connect_to_server(&serv_addr);

        initscr();
        noecho();
        keypad(stdscr, true);
        curs_set(0);
        nodelay(stdscr, true);
        start_color();
        init_pair(PLAYER_PAIR, COLOR_RED, COLOR_BLACK);
        
        clock_gettime(CLOCK_REALTIME, &cur);
        
        cur = timespec_subtract(cur, init.timestamp);
        // cur.tv_sec = init.timestamp.tv_sec - cur.tv_sec;
        // cur.tv_nsec = init.timestamp.tv_nsec - cur.tv_nsec;

        nanosleep(&cur, NULL);
        
        draw_field('#');
        
        while (true)
        {       
            draw_snakes();  
            refresh();   
            get_object(); 
            
            if ((direction = wgetch(stdscr)) != ERR)
            {
                if (direction == KEY_UP)
                    direction = MOVE_UP;
                else if (direction == KEY_DOWN)
                    direction = MOVE_DOWN;
                else if (direction == KEY_RIGHT)
                    direction = MOVE_RIGHT;
                else if (direction == KEY_LEFT)
                    direction = MOVE_LEFT;
                else
                    continue;

                Send(sock, &direction, 1, 0);
            }  
        }
    }
    else if (mod == 's')
    {
        pid_t pid;
        char *arg_exe[16] = {0};
 
        pid = Fork();
        if (pid == 0)
        {
            arg_exe[0] = "./server/snake_server";
            arg_exe[1] = "-p";
            arg_exe[2] = arg_port;
            arg_exe[3] = "-x";
            arg_exe[4] = arg_size_field_x;
            arg_exe[5] = "-y";
            arg_exe[6] = arg_size_field_y;
            arg_exe[7] = "-d";
            arg_exe[8] = arg_frame_delay;
            arg_exe[9] = "-t";
            arg_exe[10] = arg_time_stamp;
            arg_exe[11] = "-n";
            arg_exe[12] = arg_num_clients;
            arg_exe[13] = "-f";
            arg_exe[14] = arg_log_file;
            execv("./server/snake_server.exe", arg_exe);
        }
        else
        {
            sleep(1);
            arg_exe[0] = "./snake_game";
            arg_exe[1] = "-a";
            arg_exe[2] = arg_ip;
            arg_exe[3] = "-p";
            arg_exe[4] = arg_port;
            main(5, arg_exe);
        }
    }
}
